//importing javascipt core modules
Components.utils.import("resource://downloadextender/common.js");
Components.utils.import("resource://downloadextender/downloadextender.js");

if ("undefined" == typeof(downloadextender)) {
  var downloadextender = {};
};

/**
 * Controls the main window of the downloadextender extension.
 */
downloadextender.mainwindow = {  
	
	// Initialize the extension	
	startup: function() {
	  try {
	    document.getElementById("downloadextenderwindowlisten").setAttribute("checked", downloadextender.pref.listen);
		this.initshowdownloads();	
      }
	  catch (e) { downloadextender.consoleService("startup: "+e); }
	},
	
	// Clean up after ourselves 	
	shutdown: function() {

	},
	
	initshowdownloads: function() {
      try {
        //show downloads in window of download extender       
	    downloadextender.download.showDownloads();		
		downloadextender.download.showSorted();
	  }
	  catch (e) { downloadextender.consoleService("initshowdownloads: "+e); }
	},
	
	makerow: function(download) {
	  try {
		//makes rows for tree from downloadextender downloads
	    	
        let cell_enabled = document.createElement("treecell");
		let cell_leafname = document.createElement("treecell");
		let cell_contenttype = document.createElement("treecell");
		let cell_progress = document.createElement("treecell");
		let cell_speed = document.createElement("treecell");
		let cell_status = document.createElement("treecell");
		let cell_target = document.createElement("treecell");
		let cell_origin = document.createElement("treecell");

		//checkbox			
        cell_enabled.setAttribute("value", download.checked);
		if (download.checked==true) { var checked = "checked"; }
		else { var checked = "unchecked"; }	
		cell_enabled.setAttribute("value", download.checked);
		//id attribute is currently hidden in tree
		cell_enabled.setAttribute("id", download.id);	
		//leafname "filename" of download
        cell_leafname.setAttribute("label", download.localfile.leafName);
		//type of content
		cell_contenttype.setAttribute("label", download.contenttype);
		//progressbar
		cell_progress.setAttribute("mode", "normal");
        cell_progress.setAttribute("value", download.progress);
        //download speed, only show speed indication when downloading
		if (download.status == "0") {
		  //get localized speed string for speed
          let speed = downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_speed");
		  cell_speed.setAttribute("label", Math.round((download.speed)/1000)+" "+speed);
		}
		else {
		  cell_speed.setAttribute("label", "");
		}
		cell_status.setAttribute("label", downloadextender.mainwindow.localizedstatus(download.status));
		//status (e.g. -1) is hidden
		cell_status.setAttribute("status", download.status);
		//target directory of download
		cell_target.setAttribute("label", download.localfile.parent.path);
		//original URL of download
        cell_origin.setAttribute("label", download.origin);


        let row = document.createElement("treerow");
        row.appendChild(cell_enabled);
		row.appendChild(cell_leafname);
		row.appendChild(cell_contenttype);
		row.appendChild(cell_progress);
		row.appendChild(cell_speed);
		row.appendChild(cell_status);
		row.appendChild(cell_target);
        row.appendChild(cell_origin);
		
        let item = document.createElement("treeitem");
        item.appendChild(row);
        document.getElementById("downloadextenderdownloadtreechildren").appendChild(item);
	  }
      catch (e) { downloadextender.consoleService("makerow: "+e); }
	},
	updaterow: function(aDownload) {
	  try {
	    let index = -1;
	    //get download tree
	    let treechildren= document.getElementById("downloadextenderdownloadtreechildren");
		for(var i = 0; i < treechildren.childNodes.length; i++) {
		  let treeitem = treechildren.childNodes[i];
		  let treerow = treeitem.firstChild;
		  if (treerow.childNodes[0].getAttribute("id") == aDownload.id) { index = i; }
		}
		//only update when id is found
		if (index > -1) {
		//get treerow where download is
        let treerow = treechildren.childNodes[index].firstChild;
		//checkbox
	    treerow.childNodes[0].setAttribute("value", aDownload.checked);
		//id attribute is hidden
        treerow.childNodes[0].setAttribute("id", aDownload.id);
		//leafname "filename" 
        treerow.childNodes[1].setAttribute("label", aDownload.localfile.leafName);
		//contenttype		
        treerow.childNodes[2].setAttribute("label", aDownload.contenttype);
		//progress indicator
		treerow.childNodes[3].setAttribute("value", aDownload.progress);        
        //download speed, only show speed indication when downloading
		if (aDownload.status == "0") {
          //get local string of speed
		  let speed = downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_speed");
		  treerow.childNodes[4].setAttribute("label", Math.round((aDownload.speed)/1000)+" "+speed);
		}
		else {
		  treerow.childNodes[4].setAttribute("label", "");
		}
		//status
		treerow.childNodes[5].setAttribute("label", downloadextender.mainwindow.localizedstatus(aDownload.status));
		treerow.childNodes[5].setAttribute("status", aDownload.status);
		//target
		treerow.childNodes[6].setAttribute("label", aDownload.localfile.parent.path);
        //origin
		treerow.childNodes[7].setAttribute("label", aDownload.origin);
		}
	  }
	  catch (e) { downloadextender.consoleService("updaterow: "+e); }
	},
	localizedstatus: function(status) {
	  try {
	    //nsiDownloadManager constants (e.g. -1 = DOWNLOAD_NOTSTARTED)
        let stat = [];
        // -1 == not started		
	    stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_notstarted"));
		// 0 == downloading
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_downloading"));
		// 1 == finished
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_finished"));
		// 2 == failed
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_failed"));
		// 3 = canceled
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_canceled"));
		// 4 = paused
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_paused"));
		// 5 = queued
        stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_queued"));
		// 6 = blocked parental
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_blocked_parental"));
		// 7 = scanning for virus
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_scanning"));
		// 8 = virus detected
		stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_dirty"));
		// 9 = blocked policy
        stat.push(downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_blocked_policy"));
		//return localized string
		return stat[status+1];		
	  }
	  catch (e) { downloadextender.consoleService("localizedstatus: "+e); }
	},
	ontreeclick: function(event) {
      try {	
        //reverse checkbox when checkbox is clicked	  
		let tree = document.getElementById("downloadextender-tree");		
		let row = {}, column = {}, obj = {};
        let boxobject = tree.boxObject;
        boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
        boxobject.getCellAt(event.clientX, event.clientY, row, column, obj);
		
        //only reverse check when checkbox is clicked
        if (column.value != null && column.value.id == "downloadextenderenabled") {
		  //get columnid
		  let columnid = tree.columns.getNamedColumn("downloadextenderenabled");
		  //reverse checkbox
		  if (tree.view.getCellValue(tree.currentIndex, columnid)=="true") {
		    boolchecked = false;
			checked = "unchecked";
		  }
		  else {
		    boolchecked = true;
			checked = "checked";
          }		   
		  let selection = tree.contentView.getItemAtIndex( tree.currentIndex );
		  selection.firstChild.firstChild.setAttribute("value", boolchecked);
		  
		  //update download in the array
		  let index = tree.currentIndex;
		  let treeitem = tree.view.getItemAtIndex(index);
          let id = treeitem.firstChild.childNodes[0].getAttribute("id");
		  let download = downloadextender.download.findDownload(id);
		  download.checked = boolchecked;
		  downloadextender.download.updatearray(download);
		}	
      }
	  catch (e) { downloadextender.consoleService("ontreeclick: "+e); }
	},
	ontreedblclick: function(event) {
	  try {
	    //doubleclick executes the finished download by OS
		let tree = document.getElementById("downloadextender-tree");
        let index = tree.currentIndex;
		if (index > -1) {
          let treeitem = tree.view.getItemAtIndex(index);
          let status = treeitem.firstChild.childNodes[5].getAttribute("status");
		  //only executes the download by OS when download is finished
		  if (status == "1") {
		    let id = treeitem.firstChild.childNodes[0].getAttribute("id");  
		    let download = downloadextender.download.findDownload(id);
            let nsilocalfile = downloadextender.nsilocalfile();
		    nsilocalfile.initWithFile(download.localfile);
		    //checks if file exists,can be be read by user en is an actual file then launches the file by OS
		    if (nsilocalfile.exists() && nsilocalfile.isReadable()&& nsilocalfile.isFile()) { nsilocalfile.launch(); }		  
	      }
		}
	  }
	  catch (e) { downloadextender.consoleService("ontreedblclick: "+e); }
	},	
	onclear: function() {
	  try {
	    let treechildren= document.getElementById("downloadextenderdownloadtreechildren");
		for(var i = (treechildren.childNodes.length-1); i > -1; i--) {
		  let treeitem = treechildren.childNodes[i];
		  let treerow = treeitem.firstChild;
		  let status = treerow.childNodes[5].getAttribute("status");
		  //only clear downloaded files, actual files on hard disc are not deleted
		  if (status == "1") {
		    let id = treerow.childNodes[0].getAttribute("id");
			//delete from array
		    downloadextender.download.deleteDownload(id);
			//delete from tree
            treeitem.parentNode.removeChild(treeitem);
		  }
	    }
	  }
	  catch (e) { downloadextender.consoleService("onclear: "+e); }
	},
	onabort: function() {
	  try {
	    let treechildren= document.getElementById("downloadextenderdownloadtreechildren");
		
		let abortwarningheader = downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_abort_warningheader");
		let abortwarning = downloadextender.getlocalisedstring("mainwindow.properties", "downloadextender_abort_warning");
		let promptservice = downloadextender.promptservice();
		let confirm = promptservice.confirm(null, abortwarningheader, abortwarning);
		
        if (confirm == true) {		
		  for(var i = (treechildren.childNodes.length-1); i > -1; i--) {
		    let treeitem = treechildren.childNodes[i];
		    let treerow = treeitem.firstChild;
		    let checked = treerow.childNodes[0].getAttribute("value");	
		  
		    if (checked=="true") {
		      let id = treerow.childNodes[0].getAttribute("id");
              let download = downloadextender.download.findDownload(id);
              let status = treerow.childNodes[5].getAttribute("status");
			
			  //only abort the download when download is still downloading, cancels the download through downloadmanager of Firefox
			  if (status == "0") { 
	          let appinfo = downloadextender.appinfo(); 
		        let versionchecker = downloadextender.versioncomparator();
                if (versionchecker.compare(appinfo.version, 20) >=0) { 
			      //in case of Firefox 20 or later
				  downloadextender.dm().getDownloadByGUID(download.dmid, function(aStatus, aResult) {
				    let canceleddownload = aResult;
				    canceleddownload.cancel();
				    if (!Components.isSuccessCode(aStatus)) {
				      downloadextender.consoleService("Cannot retrieve download for GUID: " + this.downloadGuid); 
			        }   
				    else {
			          this._download = aResult;				  
			        }
			      });

                }
                else {
                  //in case of Firefox 19 or below
                  downloadextender.dm().cancelDownload(download.dmid);
				  //deletes file from disc if possible
			      let localfile = downloadextender.nsilocalfile();
                  localfile.initWithFile(download.localfile);
			      //checks if file exists,can be be read by user en is an actual file then deletes the file
                  if(localfile.exists() && localfile.isReadable() && localfile.isFile()) { localfile.remove(false) };
                }	
			  }
			  else {
			    //e.g. delete a corrupted download
			    //deletes file from disc if possible
			    let localfile = downloadextender.nsilocalfile();
                localfile.initWithFile(download.localfile);
			    //checks if file exists,can be be read by user en is an actual file then deletes the file
                if(localfile.exists() && localfile.isReadable() && localfile.isFile()) { localfile.remove(false) };
			  }
			  //remove download from array	
		      downloadextender.download.deleteDownload(id);
			  //delete download from tree
              treeitem.parentNode.removeChild(treeitem);
		    }
	      }
		}
	  }
	  catch (e) { downloadextender.consoleService("onabort: "+e); }
	},
    onrename: function() {
	  try {
	    //rename the download when download is finished or hasn't started
		let tree = document.getElementById("downloadextender-tree");
        let index = tree.currentIndex;
        let treeitem = tree.view.getItemAtIndex(index);
		
        let status = treeitem.firstChild.childNodes[5].getAttribute("status");
		if (status == "1" || "-1") {
		  let id = treeitem.firstChild.childNodes[0].getAttribute("id");  
		  let download = downloadextender.download.findDownload(id);
		  let filepicker = downloadextender.filepicker();
          filepicker.init(window, "", filepicker.modeSave);
          filepicker.defaultString = download.localfile.leafName;
          filepicker.displayDirectory = download.localfile.parent;
          filepicker.appendFilters(filepicker.filterAll);
          let result = filepicker.show();
		  let localfile = downloadextender.nsilocalfile();
		  localfile.initWithFile(download.localfile);	
          if (result == filepicker.returnOK || result == filepicker.returnReplace) {		  
	  
		  //only moves when completed download is present, readeable & is a file
		    if(localfile.exists()&& localfile.isReadable() && localfile.isFile()) { 
		      localfile.moveTo(filepicker.file.parent, filepicker.file.leafName);
			  download.localfile = filepicker.file;
			  downloadextender.download.updatearray(download);			  
		    }
			//rename when file doesn't exist
			else if (!localfile.exists()) {
			  download.localfile = filepicker.file;
			  downloadextender.download.updatearray(download);	
			}
		  }		  
	    }
	  }
	  catch (e) { downloadextender.consoleService("onrename: "+e); }
	},
	onopentargetdirectory: function() {
	  try {
	    let tree = document.getElementById("downloadextender-tree");
        let index = tree.currentIndex;
		if (index > -1) {
        let treeitem = tree.view.getItemAtIndex(index);
		  let id = treeitem.firstChild.childNodes[0].getAttribute("id");
		  let download = downloadextender.download.findDownload(id);
		  let localfile = downloadextender.nsilocalfile();
		  localfile.initWithFile(download.localfile);
		  //opens target directory with file selected
		  if(localfile.exists()&& localfile.isReadable() && localfile.isFile()) {
		    localfile.reveal();
		  }
		  else {
		    //show download directory of Firefox
		    localfile.initWithPath(downloadextender.downloaddir().path);
			localfile.reveal();
		  }
		}
		
	  }
	  catch (e) { downloadextender.consoleService("onopentargetdirectory: "+e); }
	},
    oncolumncheckbox: function(column) {
	  try {
	    if (column) {
            downloadextender.download.selectionall();
		}		
	  }
      catch (e) { downloadextender.consoleService("oncolumncheckbox: "+e); }
	},
    ondownload: function() {
	  try {
	    let treechildren= document.getElementById("downloadextenderdownloadtreechildren");
		for(var i = 0; i < treechildren.childNodes.length; i++) {
		  let treeitem = treechildren.childNodes[i];
		  let treerow = treeitem.firstChild;		  
		  let checked = treerow.childNodes[0].getAttribute("value");
		  let status = treerow.childNodes[5].getAttribute("status");
		  //only download those who are checked and aren't downloading
		  if (checked == "true" && status == "-1") {
			let id = treerow.childNodes[0].getAttribute("id");
			let download = downloadextender.download.findDownload(id);
			//start the download of the checked rows
			downloadextender.BrowserOverlay.autodownload(download);
		  }
		}			
	  }
	  catch (e) { downloadextender.consoleService("ondownload: "+e); }
	},	
    listen: function() {
	  try {
	    downloadextender.BrowserOverlay.listen();
	  }
	  catch (e) { downloadextender.consoleService("window listen: "+e); }
	},
	refreshlistencheckbox: function() {
	  try {
		document.getElementById("downloadextenderwindowlisten").setAttribute("checked", downloadextender.pref.listen);
	  }
	  catch (e) { downloadextender.consoleService("refreshlistencheckbox: "+e); }
	},
	makesorted: function(column,sorted) {
	  try {
	  if (sorted != null) {
	  if (column == 0) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextendername").setAttribute("sortDirection","descending");
		}
		else if (sorted == "ascending") {
		document.getElementById("downloadextendername").setAttribute("sortDirection","ascending");
		}
	  }
	  else if (column == 1) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextendertype").setAttribute("sortDirection","descending");
		}
		else {
		document.getElementById("downloadextendertype").setAttribute("sortDirection","ascending");
		}
	  }
	  else if (column == 2) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextenderprogress").setAttribute("sortDirection","descending");
		}
		else {
		document.getElementById("downloadextenderprogress").setAttribute("sortDirection","ascending");
		}
	  }
	  else if (column == 3) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextenderspeed").setAttribute("sortDirection","descending");
		}
		else {
		document.getElementById("downloadextenderspeed").setAttribute("sortDirection","ascending");
		}
	  }
	  else if (column == 4) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextenderstatus").setAttribute("sortDirection","descending");
		}
		else {
		document.getElementById("downloadextenderstatus").setAttribute("sortDirection","ascending");
		}
	  }
	  else if (column == 5) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextendertarget").setAttribute("sortDirection","descending");
		}
		else {
		document.getElementById("downloadextendertarget").setAttribute("sortDirection","ascending");
		}
	  }
	  else if (column == 6) {
	    if (sorted == "decending") {
	    document.getElementById("downloadextenderorigin").setAttribute("sortDirection","descending");
		}
		else {
		document.getElementById("downloadextenderorigin").setAttribute("sortDirection","ascending");
		}
	  }
	  }
	  }
	  catch (e) { downloadextender.consoleService("makesorted: "+e); }
	},
	sort: function(column) {
	  try {
	    let order;
	    let columnName;
		
		if (column) {
		  columnName = column.id;
		  order = document.getElementById(columnName).getAttribute("sortDirection");
		  let reverseorder = (order=="ascending") ? "decending" : "ascending";
          downloadextender.download.onsort(reverseorder, columnName);
		  let treechildren= document.getElementById("downloadextenderdownloadtreechildren");
		  for(var i = (treechildren.childNodes.length-1); i > -1; i--) {
		    let treeitem = treechildren.childNodes[i];
			//delete from tree
            treeitem.parentNode.removeChild(treeitem);
		  }
		  downloadextender.download.showDownloads();

		  if (order == "ascending") {
		    document.getElementById(columnName).setAttribute("sortDirection","descending");
		  }
		  else {
		    document.getElementById(columnName).setAttribute("sortDirection","ascending");
		  }
	    } 
	  }
	  catch (e) { downloadextender.consoleService("sort: "+e); }
	}
}

// Install load and unload handlers
window.addEventListener("load", function(e) { downloadextender.mainwindow.startup(); }, false);
window.addEventListener("unload", function(e) { downloadextender.mainwindow.shutdown(); }, false);9